package pkg.filter;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sourceforge.stripes.util.Log;
import pkg.entity.User;

public class SecurityFilter implements Filter {

    private static Set<String> publicUrls = new HashSet<String>();
    private static Log log = Log.getInstance(SecurityFilter.class);

    static {
        publicUrls.add("/index.jsp");
        publicUrls.add("/login.jsp");
        publicUrls.add("/Logout.jsp");
        publicUrls.add("/Login.action");
        publicUrls.add("/ShowAuction.action");
        publicUrls.add("/Register.action");
        publicUrls.add("/Image.action");
    }

    /** Does nothing. */
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(ServletRequest servletRequest,
            ServletResponse servletResponse,
            FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String path = request.getServletPath();

        User user = (User) request.getSession().getAttribute("user");
        boolean allowed = false;
        if (user == null) {
            allowed = isPublicResource(request);
        } else {
            if (!user.getAdmin()) {
                allowed = isPublicResource(request) || isUserResource(request);
            } else {
                allowed = true;
            }
        }

        if (allowed) {
            filterChain.doFilter(request, response);
        } else {
            if (user == null) {
                // Not logged in at all
                // Redirect the user to the login page, noting where they were coming from
                String targetUrl = URLEncoder.encode(request.getServletPath(), "UTF-8");

                response.sendRedirect(
                        request.getContextPath() + "/Login.action?targetUrl=" + targetUrl);
            } else {
                // Logged in, but unauthorized
                response.sendRedirect(
                        request.getContextPath() + "/Login.action?unauthorized");
            }
        }
//        if (request.getSession().getAttribute("user") != null) {
//            log.debug("allowing user");
//            filterChain.doFilter(request, response);
//        } else if (isPublicResource(request)) {
//            log.debug("allowing public resouce");
//            filterChain.doFilter(request, response);
//        } else {
//            log.debug("redirecting to login page");
//            // Redirect the user to the login page, noting where they were coming from
//            String targetUrl = URLEncoder.encode(request.getServletPath(), "UTF-8");
//
//            response.sendRedirect(
//                    request.getContextPath() + "/Login.action?targetUrl=" + targetUrl);
//        }
    }

    /**
     * Method that checks the request to see if it is for a publicly accessible resource
     */
    protected boolean isPublicResource(HttpServletRequest request) {
        String resource = request.getServletPath();

        boolean result = publicUrls.contains(request.getServletPath())
                || (!resource.endsWith(".jsp") && !resource.endsWith(".action") && !resource.endsWith(".pdf"));
        log.debug("checking for public resource", resource, " = ", result);
        return result;
    }

    private boolean isUserResource(HttpServletRequest request) {
        return true;
    }

    /** Does nothing. */
    public void destroy() {
    }
}
